package com.boco.blch.runner.result.handler;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.boco.blch.runner.executor.MultipleCommandExecutor;
import com.boco.blch.runner.result.MultipleResult;
import com.boco.blch.runner.result.Result;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class MultipleResultHandler extends TrimResult{
	private static final String CHMOD_REGEX_LINE = ".*chmod\\s+?\\+x\\s[0-9a-zA-Z]{32}\\.sh";
	private static Pattern chmodLine = Pattern.compile(CHMOD_REGEX_LINE);
	/*匹配执行指令正则*/
	protected static final String EXESHELL_REGEX_LINE = ".*\\./[0-9a-zA-Z]{32}\\.sh";
	private static Pattern exeshellLine = Pattern.compile(EXESHELL_REGEX_LINE);
	private static Logger logger = Logger.getLogger(MultipleResultHandler.class);
	@Override
	public MultipleResult handler(Result r) {
		long start = System.currentTimeMillis();
		logger.info("开始执行结果解析");
//		String clearSource = clearExecCommand(r);
//		JSONArray ret = splitSource(clearSource);
		JSONArray ret = splitSource(splitToSingle(r.getMessage()));
		logger.info(r.getMessage());
		logger.info("结果解析执行完成,返回" + ret.size() + " 个结果，耗时:" + (System.currentTimeMillis() - start) + "ms");
		return new MultipleResult(ret);
	}
	
	/*=========================第一种解析逻辑(先分组，再清理每个结果的多余信息)================================*/
	/**
	 * 将一整片结果解析成一个一个的
	 * @param source
	 * @return
	 */
	private String[] splitToSingle(String source){
		String[] splitArray = source.split(MultipleCommandExecutor.OUTER_SEPERATOR);
		String[] fatSingle = new String[splitArray.length - 1];
		
		System.arraycopy(splitArray, 0, fatSingle, 0, splitArray.length - 1);
		return fatSingle;
	}
	
	/**
	 * 解析每个结果
	 * @param fatSingle
	 * @return
	 */
	private JSONObject fatSingleToThin(String fatSingle){
		JSONObject obj = new JSONObject();
		String[] details = fatSingle.split(MultipleCommandExecutor.INNER_SEPERATOR);
		if(details != null && details.length > 1){
			obj.element("compliantnumber", details[1]);
			obj.element("result", trimDetail(details[0]));
			obj.element("code", 0);
		}
		return obj;
	}
	
	private String trimDetail(String result){
		if(result.indexOf("./") >= 0){
			String[] arr = result.split(EXESHELL_REGEX);
			if(arr != null && arr.length > 1){
				return arr[1];
			} else {
				return result;
			}
		} else {
			return result;
		}
	}
	
	private JSONArray splitSource(String[] source){
		JSONArray retVal = new JSONArray();
		if(source != null){
			for(String fatSingle : source){
				retVal.element(fatSingleToThin(fatSingle));
			}
		}
		return retVal;
	}
	
	
/*=========================第二种解析逻辑================================*/
	/**
	 * 去除上次登录信息和chmod +x .sh 与 ./96d.sh 这样的行
	 * @param r
	 * @return
	 */
	private String clearExecCommand(Result r){
		if(r != null){
			String source = r.getMessage();
			int firstExecShellCharIndex = source.indexOf("./");
			if(firstExecShellCharIndex != -1){
				source = source.substring(firstExecShellCharIndex + 37, source.length());
				String[] strArr = source.split(System.getProperty("line.separator"));
				if(strArr != null && strArr.length != 0){
					StringBuilder sb = new StringBuilder();
					for(String line : strArr){
						if(!isChmodOrExec(line)){
							sb.append(line).append(System.getProperty("line.separator"));
						}
					}
					return sb.toString();
				}
			}
			return source;
		}
		return null;
	}
	
	private boolean isChmodOrExec(String line){
		Matcher chmodMatcher = chmodLine.matcher(line);
		Matcher ExecMatcher = exeshellLine.matcher(line);
		return chmodMatcher.matches() || ExecMatcher.matches();
	}
	
	private JSONArray splitSource(String source){
		String[] eachEcho = source.split(MultipleCommandExecutor.OUTER_SEPERATOR);
		JSONArray retVal = new JSONArray();
		if(eachEcho != null && eachEcho.length != 0){
			for(String each : eachEcho){
				JSONObject obj = new JSONObject();
				String[] details = each.split(MultipleCommandExecutor.INNER_SEPERATOR);
				if(details != null && details.length > 1){
					obj.element("compliantnumber", details[1]);
					obj.element("result", details[0]);
					obj.element("code", 0);
					retVal.element(obj);
				}
			}
		}
		return retVal;
	}
	
	
}
